package com.gengzp.rpc.strategy.impl;

import com.fasterxml.jackson.core.type.TypeReference;
import com.gengzp.rpc.core.RpcCacheCoreFunc;
import com.gengzp.rpc.enums.RpcServiceRegisterIpTypeEnum;
import com.gengzp.rpc.model.serviceRegistration.dto.ServiceRegistrationDto;
import com.gengzp.rpc.model.serviceRegistration.resp.SearchServiceRegistrationResp;
import com.gengzp.rpc.strategy.RpcRemoteServiceRouteStrategy;
import com.gengzp.rpc.tools.RpcEnvironmentVariableReader;
import com.gengzp.rpc.tools.RpcJsonConvertor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.gengzp.rpc.constants.RpcCacheKeyConstants.SERVICE_REGISTER_CACHE_KEY;
import static com.gengzp.rpc.constants.RpcHttpRequestUrlConstants.HTTP_REQUEST_URL_PREFIX;

/**
 * @ClassName RpcRemoteServiceRouteRedisStrategyImpl
 * @Description redis 服务路由策略
 * @Author gengzp
 * @Date 2025/8/26 14:35
 */
@Component
public class RpcRemoteServiceRouteRedisStrategyImpl implements RpcRemoteServiceRouteStrategy {

    @Autowired
    private RpcCacheCoreFunc rpcCacheCoreFunc;

    @Override
    public List<String> getServiceInstanceAddressByServiceName(String serviceName) {
        List<ServiceRegistrationDto> survivingRemoteServiceRegistrationInfos =
                getSurvivingRemoteServiceRegistrationInfos(serviceName);
        if (survivingRemoteServiceRegistrationInfos == null || survivingRemoteServiceRegistrationInfos.isEmpty()) {
            return Collections.emptyList();
        }

        return survivingRemoteServiceRegistrationInfos.stream()
                .map(v -> String.format("%s%s:%s", HTTP_REQUEST_URL_PREFIX, v.getIp(), v.getPort())
                ).collect(Collectors.toList());
    }

    @Override
    public List<SearchServiceRegistrationResp> getServiceRegistrationInformationByServiceName(String serviceName) {
        List<ServiceRegistrationDto> survivingRemoteServiceRegistrationInfos = getSurvivingRemoteServiceRegistrationInfos(serviceName);
        if (survivingRemoteServiceRegistrationInfos == null || survivingRemoteServiceRegistrationInfos.isEmpty()) {
            return Collections.emptyList();
        }

        return survivingRemoteServiceRegistrationInfos.stream().map(v -> {
            SearchServiceRegistrationResp resp = new SearchServiceRegistrationResp();
            resp.setServiceName(v.getServiceName());
            resp.setAddress(String.format("%s:%s", v.getIp(), v.getPort()));
            resp.setRegisterIpType(v.getRegisterIpType());
            return resp;
        }).collect(Collectors.toList());
    }

    /**
     * 查询健康服务注册信息
     *
     * @param serviceName 服务名
     * @return 服务注册信息
     */
    private List<ServiceRegistrationDto> getSurvivingRemoteServiceRegistrationInfos(String serviceName) {
        // 1.根据当前服务名查询服务注册缓存信息
        String remoteServiceRegistrationInfoStr = rpcCacheCoreFunc.get(SERVICE_REGISTER_CACHE_KEY + serviceName);
        if (remoteServiceRegistrationInfoStr == null || remoteServiceRegistrationInfoStr.isEmpty()) {
            return Collections.emptyList();
        }

        // 2.取出存活的服务注册信息, 如果当前环境是公网ip, 则禁止访问其他本地ip的远程服务
        Date currentTime = new Date();
        RpcServiceRegisterIpTypeEnum registerIpType = RpcEnvironmentVariableReader.getRegisterIpType();
        List<ServiceRegistrationDto> remoteServiceRegistrationInfos = RpcJsonConvertor
                .convertJsonToGenericObject(remoteServiceRegistrationInfoStr, new TypeReference<>() {
                });

        return remoteServiceRegistrationInfos.stream().filter(v -> {
            if (v.getExpireTime().before(currentTime)) {
                return false;
            }
            return !Objects.equals(registerIpType, RpcServiceRegisterIpTypeEnum.OUTER) ||
                    !Objects.equals(v.getRegisterIpType(), RpcServiceRegisterIpTypeEnum.INNER.getName());
        }).toList();
    }

}
